#include "stdafx.h"
#include "Renderer.h"
#include "SpriteInternal.h"
#include "Engine.h"

Graphics::Renderer::Renderer()
{
}

Graphics::Renderer::~Renderer()
{
	DL_CHK_ASSERT(mySpriteMap.size() == 0, "Sprites still left in render list");
}

void Graphics::Renderer::Update()
{
	Utilities::GrowingArray<Syncronization::Message*>& messages = Syncronization::Syncronizer::GetMessages();
	for(unsigned int i = 0; i < messages.Count(); i++)
	{
		Syncronization::Message* msg = messages[i];
		switch(msg->type)
		{
		case Syncronization::Message::ADD_SPRITE:
			{
				SpriteInternal* sprite = reinterpret_cast<Syncronization::MessageSprite*>(msg)->sprite;
				mySpriteMap.insert(std::make_pair(sprite->GetID(), sprite));
				break;
			}

		case Syncronization::Message::DELETE_SPRITE:
			{
				SpriteInternal* sprite = reinterpret_cast<Syncronization::MessageSprite*>(msg)->sprite;
				DL_CHK_ASSERT(sprite != NULL, "Sprite in message is NULL");
				std::map<unsigned int, SpriteInternal*>::iterator i = mySpriteMap.find(sprite->GetID());
				if(i != mySpriteMap.end())
				{
					delete i->second;
					mySpriteMap.erase(i);
				}
				else
				{
					DL_CRITICAL("Sprite not found in mySpriteMap");
					DL_INCREASETAB;
					DL_PRINT("Possible causes are:");
					DL_PRINT("Sprite was never added in the first place");
					DL_PRINT("Sprite has already been deleted once");
					DL_PRINT("Additional info:");
					DL_INCREASETAB;
					DL_PRINT(ExtendedString("ID: ") << sprite->GetID());
					DL_DECREASETAB;
					DL_DECREASETAB;
				}
				break;
			}
		}
	}
	
	Syncronization::Syncronizer::ClearMessages();
}

void Graphics::Renderer::Render()
{
	if(Engine::GetDevice() == NULL)
	{
		return;
	}

	// Clear the backbuffer to a blue color
	Engine::GetDevice()->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );

	HRESULT hr = Engine::GetDevice()->BeginScene();
	DL_CHK_CRITICAL(SUCCEEDED(hr), ExtendedString("Error calling BeginScene(); hr = ") << hr);
	if(SUCCEEDED(hr))
	{
		for(std::map<unsigned int, SpriteInternal*>::iterator i = mySpriteMap.begin(); i != mySpriteMap.end(); i++)
		{
			i->second->Render();
		}

		Engine::GetDevice()->EndScene();
	}

	Engine::GetDevice()->Present( NULL, NULL, NULL, NULL );
}